package com.gdufe.order.task;

import com.gdufe.order.dao.OrderDao;
import com.gdufe.common.entity.OrderEntity;
import com.gdufe.order.service.OrderAdminService;
import com.gdufe.order.vo.UserOrderDetilsVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 定时任务类，定时处理订单状态
 */
@Component
@Slf4j
public class OrderTask {

    @Autowired
    private OrderDao orderDao;
    @Autowired
    private OrderAdminService orderAdminService;
    @Autowired
    private RedisTemplate redisTemplate;
    public static final String ORDER_KEY = "orderDetails";

    //未支付订单状态
    private static final Integer ORDER_NOPAY_STATUS = 0;
    //支付失败订单状态
    private static final Integer ORDER_ERROR_STATUS = 2;
    //支付失败原因
    private static final Integer PAY_OUT_TIME = 2;

    /**
     * 定时处理超时未支付订单，每一分钟检查一次订单状态
     * 若存在超过15分钟未支付的订单则取消该订单
     */
    @Scheduled(cron = "0 * * * * ? ")
    @CacheEvict(value = "order", allEntries = true)
    public void processTimeOutOrder() {
        //获得当前时间的15分钟前的时间
        //测试为1分钟，实际应改为15分钟
        LocalDateTime time = LocalDateTime.now().plusMinutes(-1);

        //查询下单时间超过3分钟仍未支付的订单
        //select * from mini_order where status = ? and create_time < (当前时间-15分钟)
        List<OrderEntity> list = orderDao.getListNotPay(ORDER_NOPAY_STATUS, time);

        //获取操作redis hash类型的操作类
        BoundHashOperations<String, Object, Object> hashOperations = redisTemplate.boundHashOps(ORDER_KEY);

        //遍历订单并修改订单状态为支付失败
        for (OrderEntity order : list) {
            order.setStatus(ORDER_ERROR_STATUS);
            order.setPayResoult(PAY_OUT_TIME);
            orderAdminService.updateById(order);
            //订单信息更新到缓存
            UserOrderDetilsVo vo;
            if (hashOperations.hasKey(order.getId().toString())) {
                vo = (UserOrderDetilsVo) hashOperations.get(order.getId().toString());
                BeanUtils.copyProperties(order, vo);
                hashOperations.put(vo.getId().toString(), vo);
            }
        }

    }
}
